/**
 * \file map.h
 * \brief Map class header
 * \author Marc Laval
 * \version 0.1
 * \date 10/2011
 *
 */

#include "defines.h"
#include "types.h"
#include "cell.h"
#include "point.h"

#include <SDL/SDL.h>

#ifndef _MAP_H_
#define _MAP_H_

/*!
 * \class Cell
 * \brief Class representing the map
 *
 * The map is stored as a 2 dimension set of Cells.
 */
class Map {

    /*! \brief Map width in tiles*/
    uint16 m_width;

    /*! \brief Map height in tiles */
    uint16 m_height;

    /*! \brief Size of a tile in pixels */
    uint8 m_tileSize;

    /*! \brief Alle the cells composing the map */
	Cell *** m_cells;

public :

    /*! \brief Default constructor */
    Map();

    /*! \brief Constructor
     *  \param width Map width
     *  \param height Map height
     *  \param tileSize Tile size
     */
	Map(uint16 with, uint16 height, uint8 tileSize);

    /*! \brief Destructor */
	~Map();

    /*! \brief Load a map form an existing file
     *  \param filename file name
     *  \return true if success, false otherwise. */
    bool loadFromFile(std::string filename) throw Error;

    /*! \brief Save a map to a file
     *  \param filename file name
     *  \return true if success, false otherwise. */
    bool saveToFile(std::string filename) throw Error;

    /*! \brief Getter of the map width
     *  \return Map width in tiles
     */
    uint16 getWidth();

    /*! \brief Getter of map height
     *  \return Map height in tiles
     */
    uint16 getHeight();

    /*! \brief Getter of tile size. (Tiles are always square shaped so both sides have same size)
     *  \return Tile size in pixels
     */
    uint8 getTileSize();

    /*! \brief Try to get a cell from the map
     *  \param pos Position of the cell in the whole map.
     *  \return Pointer to the cell if coordinates are correct, null otherwise.
     *  \throw Error report if coordinates are incorrect
     */
	Cell* getCell(Point& pos)throw (Error);

    /*! \brief Paint the map on the screen.
     *  \param screen SDL surface to paint on the screen
     *  \param r Map area to paint on the screen. null for whole map.
     *
     * When the map is painted on the screen, it is possible to
     * only draw a limited part of the map defined by 'r'.
     * The paint method automatically computes positions to ensure
     * that coordinates (and so part of the rect) are not outside of the map.
     */
	void paint(SDL_Surface * screen, SDL_Rect * r);
};

#endif
